<?php

namespace Api\Event;

/** 
 * 礼包商品接口
 * @author Legend. <xcx_legender@qq.com>
 * @param 
 * @return 
 */

class GiftEvent extends BaseEvent 
{

	public function detail($id)
	{
		$id = (int)$id;
		$gift = service('Gift')->where(['id' => $id])->find();
		$statis = event('Cache')->statis('gift', $id);
		$gift = array_merge($gift, $statis);
		return $gift;
	}


	public function getHot($limit = 3)
	{
		$map = ['status' => 1];
		$gifts = service('Gift')->where($map)->limit($limit)->order('hot desc')->select();
		return $gifts;
	}

	public function getRecomd($limit = 1000)
	{
		$map = ['status' => 1, 'is_recomd' => 1];
		$gifts = service('Gift')->where($map)->limit($limit)->order('create_time desc')->select();
		return $gifts;
	}

	/** 
	 * [开始兑换商品]
	 * @author Legend. <xcx_legender@qq.com>
	 * @param 
	 * @return 
	 */
	public function exchange($uid, $id)
	{
		$map = [
			'object_type' 	=> 'gift',
			'object_id' 	=> (int)$id,
			'status' 		=> 0,
		];
		$code = service('Codes')->where($map)->find();
		// 判断库存
		if (!$code)
		{
			$this->error = ['err' => self::$API_ERROR['GIFT_STOCK'], 'info' => '库存不足'];
			return false;
		}
		$gift = $this->detail($id);
		$user = service('Users')->find($uid);
		// 判断积分
		if (!$user || $user['score'] < $gift['score'])
		{
			$this->error = ['err' => self::$API_ERROR['GIFT_USER_SCORE'], 'info' => '用户积分不足'];
			return false;
		}
		// 先使用积分
		$memo = ($gift['type'] == 'gamble' ? '抽奖 ' : '兑换 ') . $gift['name'] . ',使用积分'.$gift['score'];
		$res = event('User')->score_oper($uid, -$gift['score'], 'gift_'.$gift['type'], $memo, $gift['id']); 
		if (!$res)
		{
			$this->error = ['err' => self::$API_ERROR['GIFT_USER_SCORE'], 'info' => '用户积分不足'];
			return false;
		}
		// 如果是中奖  判定中奖
		if ($gift['type'] == 'gamble')
		{
			$res = $this->gamble($user, $gift);
			if (!$res)
			{
				$this->error = ['err' => self::$API_ERROR['GIFT_UNLUCKY'], 'info' => '未中奖'];
				return false;
			}
		}
		// 获取激活码绑定
		$this->bind_code($code, $uid, $gift);
		return $code['key'];
	}

	/** 
	 * [处理激活码绑定]
	 * @author Legend. <xcx_legender@qq.com>
	 * @param 
	 * @return 
	 */
	protected function bind_code(&$code, $uid, $data)
	{
		$save['status'] 	= 1;
		$save['uid'] 		= (int)$uid;
		$save['bindtime'] 	= NOW_TIME;
		$save['object_data'] = [
			'score' => $data['score'],
			'type'  => $data['type'],
		];
		$res = service('Codes')->where(['id' => $code['id']])->save($save);
		if ($res)
		{
			event('Cache')->statis('gift', $code['object_id'], 'incr', 'hot', 1);
			event('Cache')->statis('gift', $code['object_id'], 'incr', 'stock', -1);
		}
	}

	/** 
	 * [是否中奖处理]
	 * @author Legend. <xcx_legender@qq.com>
	 * @param 
	 * @return 
	 */
	protected function gamble(&$user, &$gift)
	{
		// 是否已经中奖 已经中间则无法再次中奖
		$uid = (int)$user['uid'];
		// if ($this->has_gambled($uid, $gift['id'])) return false;

		// 如果是必中用户 则直接中奖
		$red_users = explode("\r\n", $gift['gamble']['red_users']);
		if ($red_users && in_array($uid, $red_users)) return true;

		$rate = $gift['gamble']['rate'] > 0 ? $gift['gamble']['rate'] : round($gift['score']/$gift['gamble']['prize_score'], 10);
		

		// echo $rate,'|';
		if ($gift['gamble']['is_stock_rate'])
		{
			$stock_rate = $gift['stock'] / ($gift['stock'] + $gift['hot']);
			$rate *= $stock_rate;
		}

		// echo $stock_rate,'|';
		// 
		if ($gift['gamble']['is_user_rate'])
		{
			$user_gamble_count = service('ScoreLog')->where(
				[
					'action' 	 => 'gift_'.$gift['type'],
					'target_id'  =>  (int)$gift['id'],
					'uid'		 => $uid,
				]
				)->count();
			$user_rate  = 1 + log10($user_gamble_count);
		}
		
		// echo $user_gamble_count,'|';
		
		// echo $user_rate,'|';
 
	    // 概率是0.001 那么 0 - 0.001之间的数字为中奖 0.01 - 1之间未不中
		if ($rate == 0)
		{
			return false;
		}
		// echo $rate,'|';
		$gamble = mt_rand()/mt_getrandmax();  // 生成随机数
		// echo $gamble,'|';
		return $gamble <= $rate;
	}

	/** 
	 * [用户已经中奖]
	 * @author Legend. <xcx_legender@qq.com>
	 * @param 
	 * @return 
	 */
	protected function has_gambled($uid, $id)
	{
		$map = [
			'object_type' 	=> 'gift',
			'object_id' 	=> (int)$id,
			'uid' 			=> (int)$uid,
		];
		return service('Codes')->where($map)->count() > 0;
	}

	public function flush_stock($id, $flush_cache = false)
	{
		$id = (int)$id;
		$save = $flush_cache ? null : event('Cache')->statis('gift',$id);
		if (!$save)
		{
			$map = [
				'object_type' 	=> 'gift',
				'object_id' 	=> $id,
				'status' 		=> 0,
			];
			$count = service('Codes')->where($map)->count();
			$map['status'] = 1;
			$hot = service('Codes')->where($map)->count();
			$save = ['stock' => $count, 'hot' => $hot];
			#cache
			event('Cache')->statis('gift', $id, 'set', '', $save);
		}
		$where = ['id' => $id];
		service('Gift')->where($where)->save($save);
	}

}